package wsem.parser;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPathHelper;

import wsem.model.IndexJDBC;
import wsem.model.Noeud;
import wsem.model.Term_noeud;
import wsem.model.Termes;
import wsem.utils.ConstanteID;
import wsem.utils.StopList;
import wsem.utils.XMLUtils;


public class ParserXML {
	
	 private SAXBuilder saxBuilder;
	 
	 private Element racine;
	 
	 
	 private Document docBuilder;
	 
	 private wsem.model.Document documentParam;
	 
	 List<Noeud> nodeList = new ArrayList<Noeud>();
	 
	 List<Termes> termList = new ArrayList<Termes>();
	 
	 List <Term_noeud> tmList = new ArrayList<Term_noeud>();
	 
	 private StopList spList;
	 
	 private HashMap<String, Integer> freqTermFromParagraph;
	 
	 private int nbElemTotal = 0;
	 
	 private IndexJDBC bdIndex;

	 
	   public ParserXML(String pathFile,wsem.model.Document pdoc, IndexJDBC indexation){
		   
		   bdIndex = indexation;
		   freqTermFromParagraph = new HashMap<String, Integer>();
		   try
	       {
			   startStopList();
			  documentParam = pdoc;
	          lireFichier(pathFile);
	          
	          
	          
	          nbElemTotal = nodeList.size();
	          
	          
	          
	          //une fois la lecture termine, on inject tous les elements en base
	          if(nodeList.size()!=0){
	          
	        	  injectInDB();
	          }
	          
	         	          
	         
	          
	        }
	        catch(Exception e){
	        	
	        	e.printStackTrace();
	        }
		  
		   	
			
	   }
	   
	 
	private void injectInDB() throws SQLException {
		
		
		
		bdIndex.ajouterNoeud(nodeList);

		bdIndex.ajouterTerme(termList);

		// on n'oublie pas de calculer le tf

		tmList = XMLUtils.calculTFIDF(documentParam, nbElemTotal);

		bdIndex.ajouterTermNode(tmList);

	}

		private void startStopList() {
	 		System.out.println("Debut de l'analyse du document");
			// on demarre notre stopList ici
			try {
				
				URL input = getClass().getResource("/wsem/resources/stopliste.txt");
				
				spList = new StopList(input.getPath());

			} catch (IOException e) {

				e.printStackTrace();
			}
		
	}

		private void lireFichier(String fichier) throws Exception
	   {
		  saxBuilder = new SAXBuilder();
	      docBuilder = saxBuilder.build(new File(fichier));
	      racine = docBuilder.getRootElement();
	      
	      LinkedHashMap<String,List<String>> parentNode = initAllParentNode();
	      
	      
	      for(Entry<String,List<String>> parentNodeSet : parentNode.entrySet() ){
	    	  
	    	  String parentNodeUnique = parentNodeSet.getKey();
	    	  List<String> nodeSet = parentNodeSet.getValue();
	    	  
	    	  List listElement = racine.getChildren(parentNodeUnique);
	    	  System.out.println("voyons "+listElement.size()+" pour "+parentNodeUnique);
	    	  if(listElement != null){
	    		  
	    	   Iterator i = listElement.iterator();
	   	       while(i.hasNext()){
   	    		   Element courant = (Element) i.next();
	   	    	   for(String nodeS : nodeSet){
	   	    		   

	   	    		   System.out.println("node "+nodeS);
	   	    		   List element = courant.getChildren(nodeS);
	   	    		   
	   	    		   if(element.size()>0){
	   	    			   parseNode(element);
	   	    		   }
	   	    		  
	   	    	   }
	   	       }
	    	  }
	      }
	      
	      
      
	   }

	private LinkedHashMap<String, List<String>> initAllParentNode() {
		LinkedHashMap<String, List<String>> parentNodeMap =  new LinkedHashMap<>();
		
		List<String> presentationList = new LinkedList<>();
		presentationList.add("TITRE");
		presentationList.add("DESCRIPTION");
		presentationList.add("AUTEUR");
		
		List<String> recList = new LinkedList<>();
		recList.add("SEC");
		recList.add("SOUS-TITRE");
		
		
		parentNodeMap.put("PRESENTATION", presentationList);
		parentNodeMap.put("RECIT", recList);
		return parentNodeMap;
		}

	private void parseNode(List element) throws JDOMException {

		if (element.size() != 0) {
			Iterator i = element.iterator();
			while (i.hasNext()) {

				Element courant = (Element) i.next();
				
				List pList = courant.getChildren("P");
				if (pList != null) {
					traiterParagraphe(pList);
				}
				
					

			}
		}

	}

	private void traiterParagraphe(List pList) {
		
		Iterator i = pList.iterator();
	       while(i.hasNext()){
	    	   
	    	   Element courant = (Element) i.next();
	    	   
	    	   
	    	   
	    	   
	    	   String xpath = XPathHelper.getAbsolutePath(courant.getContent(0));
	    	   
	    	   
	    	   
	    	   String realPath = normaliseXpath(xpath.substring(0, xpath.length()-7));
	    	   ConstanteID.cptNode++;
	    	   Noeud nodeCurrent = new Noeud(realPath);
	    	   Noeud nodeLematise = XMLUtils.lematiseMot(courant.getValue(), spList, nodeCurrent, freqTermFromParagraph, termList);
	    	   nodeCurrent.setIdNoeud(ConstanteID.cptNode);
	    	   nodeCurrent.setIdDoc(documentParam.getIdDoc());
	    	   nodeCurrent.setTermNodeList(nodeLematise.getTermNodeList());

	    	   
	    	   nodeList.add(nodeCurrent);
	    	   documentParam.getListNoeud().add(nodeCurrent);
	       }
		
		
	}



	private String  normaliseXpath(String xpath) {
		String buildXPathNormalise = "";
		
			String[] elements = xpath.split("/");
			
				
	
			for (int i = 1; i < elements.length; i++) {
	
				if (!elements[i].endsWith("]/")) {	
	
					if (i < elements.length - 1 && !elements[i].endsWith("]")) {
						buildXPathNormalise += elements[i] + "[" + 1 + "]/";
					} else {
						if (elements[i].endsWith("]")) {
	
							buildXPathNormalise += elements[i]+"/";
	
						}
	
					}
				}
				
			}
		
		
		return buildXPathNormalise.substring(0, buildXPathNormalise.length()-1);
		
		
		
	}
	   
	   
	   
	   

}
